#include <stdio.h>

struct s
{
	int a;
	int b;
	int c;
};

struct s get_some_values(int a)
{
	struct s rt;

	rt.a = a + 1;
	rt.b = a + 2;
	rt.c = a + 3;

	return rt;
}

void main()
{
	struct s ac;

	ac = get_some_values(0);
	printf("%d %d %d\n", ac.a, ac.b, ac.c);		// 1 2 3
}



#if 0

C99 支持的语法来写

struct s get_some_values(int a)
{
	return (struct s){.a=a+1, .b=a+2, .c=a+3};
}

调用方函数(caller)创建了数据结构、分配了数据空间，被调用的函数仅向结构体填充数据，其效果等同于返回结构体。
这种处理方法并不会影响程序性能。

#endif

#if 0
get_some_values:
   0x555555555149:      endbr64			$rsp = (void *) 0x7fffffffe128	$rbp = (void *) 0x7fffffffe140
   0x55555555514d:      push   %rbp			$rsp = (void *) 0x7fffffffe128	$rbp = (void *) 0x7fffffffe140
   0x55555555514e:      mov    %rsp,%rbp		$rsp = (void *) 0x7fffffffe120	$rbp = (void *) 0x7fffffffe120
   0x555555555151:      mov    %edi,-0x24(%rbp)	$rsp = (void *) 0x7fffffffe120	$rbp = (void *) 0x7fffffffe120 -0x24(%rbp)=0-->0x7fffffffe0fc: 0x00000000  
   0x555555555154:      mov    -0x24(%rbp),%eax	// eax=0
   0x555555555157:      add    $0x1,%eax		// eax=1,	rax=1
   0x55555555515a:      mov    %eax,-0x18(%rbp)	$rsp = (void *) 0x7fffffffe120	$rbp = (void *) 0x7fffffffe120	$rbp-0x18=0x7fffffffe108: 0x00000001
   0x55555555515d:      mov    -0x24(%rbp),%eax	// eax=0
   0x555555555160:      add    $0x2,%eax		// eax=2
   0x555555555163:      mov    %eax,-0x14(%rbp)	// -0x14(%rbp)=0x7fffffffe10c: 0x00000002
   0x555555555166:      mov    -0x24(%rbp),%eax	// eax=0
   0x555555555169:      add    $0x3,%eax		// eax=3
   0x55555555516c:      mov    %eax,-0x10(%rbp)	// -0x10(%rbp)=0x7fffffffe110: 0x00000003
   0x55555555516f:      mov    -0x18(%rbp),%rax	// rax=0x200000001
   0x555555555173:      mov    %rax,-0xc(%rbp)	// -0xc(%rbp)=0x7fffffffe114: 0x00000001
   0x555555555177:      mov    -0x10(%rbp),%eax	// eax=3
   0x55555555517a:      mov    %eax,-0x4(%rbp)	// -0x4(%rbp)=0x7fffffffe11c: 0x00000003
   0x55555555517d:      mov    -0xc(%rbp),%rax	// rax=0x200000001
   0x555555555181:      mov    -0x4(%rbp),%ecx	// ecx=3
   0x555555555184:      mov    %rcx,%rdx		// rdx=3
   0x555555555187:      pop    %rbp				// $rsp = (void *) 0x7fffffffe128 $rbp = (void *) 0x7fffffffe140
   0x555555555188:      retq   

main:
   0x555555555189:      endbr64 
   0x55555555518d:      push   %rbp				$rsp = (void *) 0x7fffffffe140	$rbp = (void *) 0x0
   0x55555555518e:      mov    %rsp,%rbp		$rsp = (void *) 0x7fffffffe140	$rbp = (void *) 0x7fffffffe140
   0x555555555191:      sub    $0x10,%rsp		$rsp = (void *) 0x7fffffffe130	$rbp = (void *) 0x7fffffffe140	
   0x555555555195:      mov    $0x0,%edi		$rsp = (void *) 0x7fffffffe130	$rbp = (void *) 0x7fffffffe140	edi=0
   0x55555555519a:      callq  0x555555555149	
   0x55555555519f:      mov    %rax,-0xc(%rbp)	$rsp = (void *) 0x7fffffffe130	$rbp = (void *) 0x7fffffffe140 rax=0x200000001	-0xc(%rbp)=0x7fffffffe134: 0x00000001
   0x5555555551a3:      mov    -0x4(%rbp),%eax	rbp-0x4=0x7fffffffe13c: 0x00000000, eax=0
   0x5555555551a6:      and    $0x0,%eax		eax=0, edx=3
   0x5555555551a9:      or     %edx,%eax		// edx=3, eax=3
   0x5555555551ab:      mov    %eax,-0x4(%rbp)	// -0x4(%rbp)=0x7fffffffe13c: 0x00000003
   0x5555555551ae:      mov    -0x4(%rbp),%ecx	// ecx=3	
   0x5555555551b1:      mov    -0x8(%rbp),%edx	// edx=2	-0x8(%rbp)=0x7fffffffe138: 0x00000002
   0x5555555551b4:      mov    -0xc(%rbp),%eax	// eax=1	-0xc(%rbp)=0x7fffffffe134: 0x00000001
   0x5555555551b7:      mov    %eax,%esi		// esi=1
   0x5555555551b9:      lea    0xe44(%rip),%rdi        # 0x555555556004
   0x5555555551c0:      mov    $0x0,%eax
   0x5555555551c5:      callq  0x555555555050 <printf@plt>	// printf(rdi, esi, edx, ecx)

#endif


#if 0
/*
 * intel-64
 */
0000000000001149 <get_some_values>:
    1149:	f3 0f 1e fa          	endbr64 
    114d:	55                   	push   %rbp
    114e:	48 89 e5             	mov    %rsp,%rbp
    1151:	89 7d dc             	mov    %edi,-0x24(%rbp)	// (rbp-0x24)=edi=a
    1154:	8b 45 dc             	mov    -0x24(%rbp),%eax	// eax=(rbp-0x24)=a
    1157:	83 c0 01             	add    $0x1,%eax		// eax+=1 ===> a+1
    115a:	89 45 e8             	mov    %eax,-0x18(%rbp)	// (rbp-0x18)=a+1

    115d:	8b 45 dc             	mov    -0x24(%rbp),%eax	// eax=(rbp-0x24)=a
    1160:	83 c0 02             	add    $0x2,%eax		// eax+=2 ===> a+2
    1163:	89 45 ec             	mov    %eax,-0x14(%rbp)	// (rbp-0x14)=a+2	

    1166:	8b 45 dc             	mov    -0x24(%rbp),%eax	// eax=(rbp-0x24)=a
    1169:	83 c0 03             	add    $0x3,%eax		// eax+=3  ===> a+3
    116c:	89 45 f0             	mov    %eax,-0x10(%rbp)	// (rbp-0x10)=a+3

    116f:	48 8b 45 e8          	mov    -0x18(%rbp),%rax	// rax=(rbp-0x18)=a+1
    1173:	48 89 45 f4          	mov    %rax,-0xc(%rbp)	// (rbp-0xc)=a+1

    1177:	8b 45 f0             	mov    -0x10(%rbp),%eax	// eax=(rbp-0x10)=a+3
    117a:	89 45 fc             	mov    %eax,-0x4(%rbp)	//(rbp-0x4)=a+3

    117d:	48 8b 45 f4          	mov    -0xc(%rbp),%rax	// rax=a+1
    1181:	8b 4d fc             	mov    -0x4(%rbp),%ecx	// ecx=a+3
    1184:	48 89 ca             	mov    %rcx,%rdx
    1187:	5d                   	pop    %rbp
    1188:	c3                   	retq  

0000000000001189 <main>:
    1189:	f3 0f 1e fa          	endbr64 
    118d:	55                   	push   %rbp
    118e:	48 89 e5             	mov    %rsp,%rbp
    1191:	48 83 ec 10          	sub    $0x10,%rsp	// rsp-=0x10
    1195:	bf 00 00 00 00       	mov    $0x0,%edi	// edi=0
    119a:	e8 aa ff ff ff       	callq  1149 <get_some_values>	// get_some_values(edi)
    119f:	48 89 45 f4          	mov    %rax,-0xc(%rbp)			// rax为返回值
    11a3:	8b 45 fc             	mov    -0x4(%rbp),%eax
    11a6:	83 e0 00             	and    $0x0,%eax
    11a9:	09 d0                	or     %edx,%eax
    11ab:	89 45 fc             	mov    %eax,-0x4(%rbp)
    11ae:	8b 4d fc             	mov    -0x4(%rbp),%ecx
    11b1:	8b 55 f8             	mov    -0x8(%rbp),%edx
    11b4:	8b 45 f4             	mov    -0xc(%rbp),%eax
    11b7:	89 c6                	mov    %eax,%esi
    11b9:	48 8d 3d 44 0e 00 00 	lea    0xe44(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    11c0:	b8 00 00 00 00       	mov    $0x0,%eax
    11c5:	e8 86 fe ff ff       	callq  1050 <printf@plt>
    11ca:	90                   	nop
    11cb:	c9                   	leaveq 
    11cc:	c3                   	retq   
    11cd:	0f 1f 00             	nopl   (%rax)

/*
 * intel-32
 */
08048430 <get_some_values>:
 8048430:	55                   	push   %ebp
 8048431:	89 e5                	mov    %esp,%ebp
 8048433:	83 ec 10             	sub    $0x10,%esp

 8048436:	8b 45 0c             	mov    0xc(%ebp),%eax
 8048439:	83 c0 01             	add    $0x1,%eax
 804843c:	89 45 f4             	mov    %eax,-0xc(%ebp)	// (ebp-0xc)=a+1

 804843f:	8b 45 0c             	mov    0xc(%ebp),%eax
 8048442:	83 c0 02             	add    $0x2,%eax
 8048445:	89 45 f8             	mov    %eax,-0x8(%ebp)	// (ebp-0x8)=a+2

 8048448:	8b 45 0c             	mov    0xc(%ebp),%eax
 804844b:	83 c0 03             	add    $0x3,%eax
 804844e:	89 45 fc             	mov    %eax,-0x4(%ebp)	// (ebp-0x4)=a+3

 8048451:	8b 45 08             	mov    0x8(%ebp),%eax	// eax=(ebp+0x8)	获取到传过来的栈地址
 8048454:	8b 55 f4             	mov    -0xc(%ebp),%edx	// edx=a+1
 8048457:	89 10                	mov    %edx,(%eax)	// (eax)=a+1

 8048459:	8b 55 f8             	mov    -0x8(%ebp),%edx	// edx=a+2
 804845c:	89 50 04             	mov    %edx,0x4(%eax)	// (eax+0x4)=a+2

 804845f:	8b 55 fc             	mov    -0x4(%ebp),%edx	// edx=a+3
 8048462:	89 50 08             	mov    %edx,0x8(%eax)	// (eax+0x8)=a+3
 8048465:	8b 45 08             	mov    0x8(%ebp),%eax	// eax=(ebp+8)
 8048468:	c9                   	leave  
 8048469:	c2 04 00             	ret    $0x4

0804846c <main>:
 804846c:	8d 4c 24 04          	lea    0x4(%esp),%ecx
 8048470:	83 e4 f0             	and    $0xfffffff0,%esp
 8048473:	ff 71 fc             	pushl  -0x4(%ecx)
 8048476:	55                   	push   %ebp
 8048477:	89 e5                	mov    %esp,%ebp
 8048479:	51                   	push   %ecx
 804847a:	83 ec 24             	sub    $0x24,%esp
 804847d:	8d 45 ec             	lea    -0x14(%ebp),%eax		// eax=ebp-0x14	获取栈地址
 8048480:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)		// (esp+0x4)=0	参数
 8048487:	00 
 8048488:	89 04 24             	mov    %eax,(%esp)		// (esp)=eax		通过esp把栈地址传给调用函数
 804848b:	e8 a0 ff ff ff       	call   8048430 <get_some_values>	// get_some_values(esp)

 8048490:	83 ec 04             	sub    $0x4,%esp
 8048493:	8b 4d f4             	mov    -0xc(%ebp),%ecx		// exc=(ebp-0xc)
 8048496:	8b 55 f0             	mov    -0x10(%ebp),%edx		// edx=(ebp-0x10)
 8048499:	8b 45 ec             	mov    -0x14(%ebp),%eax		// eax=(ebp-0x14)
 804849c:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
 80484a0:	89 54 24 08          	mov    %edx,0x8(%esp)
 80484a4:	89 44 24 04          	mov    %eax,0x4(%esp)
 80484a8:	c7 04 24 54 85 04 08 	movl   $0x8048554,(%esp)
 80484af:	e8 3c fe ff ff       	call   80482f0 <printf@plt>	// printf(esp, esp+4, esp+8, esp+c)
 80484b4:	8b 4d fc             	mov    -0x4(%ebp),%ecx
 80484b7:	c9                   	leave  
 80484b8:	8d 61 fc             	lea    -0x4(%ecx),%esp
 80484bb:	c3                   	ret    
 80484bc:	66 90                	xchg   %ax,%ax
 80484be:	66 90                	xchg   %ax,%ax

/*
 * arm
 */
000000000040055c <get_some_values>:
  40055c:	d100c3ff 	sub	sp, sp, #0x30
  400560:	b9000fe0 	str	w0, [sp, #12]	// [sp+12]=w0
  400564:	b9400fe0 	ldr	w0, [sp, #12]	// w0=[sp+12]
  400568:	11000400 	add	w0, w0, #0x1	// w0=a+1
  40056c:	b90013e0 	str	w0, [sp, #16]	// [sp+16]=a+1
  400570:	b9400fe0 	ldr	w0, [sp, #12]	// w0=a
  400574:	11000800 	add	w0, w0, #0x2	// w0=a+2
  400578:	b90017e0 	str	w0, [sp, #20]	// [sp+20]=a+2
  40057c:	b9400fe0 	ldr	w0, [sp, #12]	// w0=a
  400580:	11000c00 	add	w0, w0, #0x3	// w0=a+3
  400584:	b9001be0 	str	w0, [sp, #24]	// [sp+24]=a+3
  400588:	910083e0 	add	x0, sp, #0x20	// x0=sp+0x20
  40058c:	910043e1 	add	x1, sp, #0x10	// x1=sp+0x10
  400590:	f9400022 	ldr	x2, [x1]		// x2=[sp+0x10]
  400594:	f9000002 	str	x2, [x0]		// [sp+0x20]=x2
  400598:	b9400821 	ldr	w1, [x1, #8]	// w1=[x1+8]
  40059c:	b9000801 	str	w1, [x0, #8]	// [x0+8]=w1
  4005a0:	d2800000 	mov	x0, #0x0                   	// #0
  4005a4:	b94023e1 	ldr	w1, [sp, #32]
  4005a8:	b3407c20 	bfxil	x0, x1, #0, #32
  4005ac:	b94027e1 	ldr	w1, [sp, #36]
  4005b0:	b3607c20 	bfi	x0, x1, #32, #32
  4005b4:	d2800001 	mov	x1, #0x0                   	// #0
  4005b8:	b9402be2 	ldr	w2, [sp, #40]
  4005bc:	b3407c41 	bfxil	x1, x2, #0, #32
  4005c0:	aa0003e3 	mov	x3, x0
  4005c4:	aa0103e4 	mov	x4, x1
  4005c8:	aa0303e0 	mov	x0, x3
  4005cc:	aa0403e1 	mov	x1, x4
  4005d0:	9100c3ff 	add	sp, sp, #0x30
  4005d4:	d65f03c0 	ret

00000000004005d8 <main>:
  4005d8:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  4005dc:	910003fd 	mov	x29, sp
  4005e0:	52800000 	mov	w0, #0x0                   	// #0
  4005e4:	97ffffde 	bl	40055c <get_some_values>
  4005e8:	2a0003e2 	mov	w2, w0
  4005ec:	b90013a2 	str	w2, [x29, #16]
  4005f0:	d360fc02 	lsr	x2, x0, #32
  4005f4:	b90017a2 	str	w2, [x29, #20]
  4005f8:	2a0103e0 	mov	w0, w1
  4005fc:	b9001ba0 	str	w0, [x29, #24]
  400600:	b94013a1 	ldr	w1, [x29, #16]
  400604:	b94017a2 	ldr	w2, [x29, #20]
  400608:	b9401ba3 	ldr	w3, [x29, #24]
  40060c:	90000000 	adrp	x0, 400000 <_init-0x3e8>
  400610:	911b6000 	add	x0, x0, #0x6d8
  400614:	97ffff8f 	bl	400450 <printf@plt>
  400618:	d503201f 	nop
  40061c:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400620:	d65f03c0 	ret
  400624:	00000000 	.inst	0x00000000 ; undefined

#endif

